/*
 * Group 3, User Interface Programming II (vt11)
 * Pooya | Flora | Monica | Can
 */
package vical.view;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JTextArea;
import javax.swing.Timer;
import javax.swing.text.JTextComponent;
import vical.action.RedoAction;
import vical.action.UndoAction;
import vical.undo.UndoManager;
import vical.undo.UndoableTextInsertEvent;

/**
 * The TextArea that supports Undo / Redo Events
 * @author Can
 */
public class UndoableTextArea extends JTextArea {

    private UndoableTextInsertEvent insertEvent;
    private Timer typingTimer;
    private UndoManager undoManager;
    private JPopupMenu popMenu;

    public UndoableTextArea() {
        undoManager = new UndoManager();

        // popMenu
        popMenu = new JPopupMenu();
        popMenu.add(new JMenuItem(new UndoAction(undoManager)));
        popMenu.add(new JMenuItem(new RedoAction(undoManager)));

        this.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getButton() == MouseEvent.BUTTON3) { // right click
                    popMenu.show(e.getComponent(), e.getX(), e.getY());
                    popMenu.setVisible(true);
                } else {
                    popMenu.setVisible(false);
                }
            }
        });

        // timer
        typingTimer = new Timer(1000, new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                insertEvent = null;
                typingTimer.stop();
            }
        });

        this.addKeyListener(new KeyAdapter() {

            @Override
            public void keyTyped(KeyEvent e) {
                if (typingTimer.isRunning()) {
                    typingTimer.restart();
                } else {
                    typingTimer.start();
                }
                if (insertEvent == null) {
                    insertEvent = new UndoableTextInsertEvent(String.valueOf(e.getKeyChar()),
                            (JTextComponent) e.getSource());
                    undoManager.registerEvent(insertEvent);
                } else {
                    insertEvent.appendText(String.valueOf(e.getKeyChar()));
                }
                if (e.getKeyChar() == ' ' || e.getKeyChar() == '\n') {
                    insertEvent = null;
                }
            }
        });
    }
}
